# coding: utf-8

import asyncio

async def delay(n):
    print(f'delay for {n} seconds')
    await asyncio.sleep(n)
    print(f'delay for {n} seconds done')
    return n
# 根据协程创建任务对象

async def main():
    sleep_for_three = asyncio.create_task(delay(3))
    # <class '_asyncio.Task'>
    print(type(sleep_for_three))

    sleep_again = asyncio.create_task(delay(3))
    sleep_once_more = asyncio.create_task(delay(3))

    # await 可以是一个协程对象，也可以是一个任务对象
    await sleep_for_three 
    await sleep_again
    await sleep_once_more
    # 任务并发执行， 第一个任务阻塞， 第二个任务开始执行
    # 注意到， 它和协程对象的区别在于， 任务对象是可以并发执行的，
    # 而直接调用协程对象是不能并发执行的
    # delay for 3 seconds
    # delay for 3 seconds
    # delay for 3 seconds
    # delay for 3 seconds done
    # delay for 3 seconds done
    # delay for 3 seconds done

    # task 是协程对象的包装器， 它安排协程尽快在 event loop 中执行
    # 任务是协程的包装器，它安排协程尽快在事件循环上运行。
    # 这种调度和执行以非阻塞方式发生，这这意味着一旦创建一个任务，就可以在任务运行时立即执行其他代码。
    # 这与使用阻塞方式的 await 关键字形成对比，意味着暂停整个协程，直到await表达式的结果返回。

asyncio.run(main())